from random import choices
import sys
import argparse

population = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'OTHER']
weights = [2, 2, 2, 2.5, 2.5, 2.5, 0.5]
weights.append(100 - sum(weights))
targets0 = set(['a', 'b', 'c', 'd', 'e', 'f'])
seperators = [0.1, 0.25, 0.5, 0.75, 0.9, 0.99]

def get_arg(i, default):
    if len(sys.argv) > i:
        return sys.argv[i]
    return default
N = int(get_arg(1, 10000)) #模拟人数
M = int(get_arg(2, 400)) #建造次数上限
B = int(get_arg(3, 20)) #柱状图柱子的个数
W = M // B
BAR_WIDTH = int(get_arg(4, 200)) #柱状图最大长度

print('---碧蓝航线建造模拟器v1.1---')
print(f'模拟分布：', end='')
for i in range(len(population)):
    print(f'{population[i]}={weights[i]}% ', end='')
print(f'\n目标：' + str(targets0))
print(f'共模拟{N}人')

samples = [0] * (M + 1)
buckets = [0] * (B + 1)
for i in range(N):
    k = 0
    targets = set(targets0)
    while len(targets) > 0 and k <= M:
        k += 1
        c = choices(population, weights)[0]
        if c in targets:
            targets.remove(c)
    if k <= M:
        samples[k] += 1
        buckets[k // W] += 1
    else:
        samples[-1] += 1
        buckets[-1] += 1

def numSampleToBarHeight(n):
    if n == 0:
        return 0
    return int(n / N * BAR_WIDTH) + 1
c = 0
acc = [buckets[0]]
for i in range(1, len(buckets)):
    acc.append(acc[-1] + buckets[i])
print('------模拟结果------')
def showRow(buckets, i, msg=None, padding=12):
    msg = f'{i*W}~{(i+1)*W-1}发' if not msg else msg
    bar = "*" * numSampleToBarHeight(buckets[i])
    print(f'{msg: <{padding}}：{bar}    {buckets[i]}人（{buckets[i]/N*100:.2f}%）（{acc[i]/N*100:.2f}%）')
for i in range(B):
    showRow(buckets, i)
showRow(buckets, B, f'{B*W}发以上', 10)
print('--------------------')
for i in range(M):
    if samples[i] != 0:
        c += samples[i]
        if len(seperators) > 0 and c >= seperators[0] * N:
            print(f'{seperators[0] * 100}%的人在{i}发内毕业')
            seperators = seperators[1:]




        


